1 Read, Clean, Recode, Merge

2 Sample descriptives

## Number of subjects
## Number of subjects per Protocol

3 Season Memories and Valence

3.1 Make data frames

## Exclude P6 & P7
Data_Season <- 
  Data %>%
  dplyr::filter(!Protocol %in% c(6, 7))

## Melt to Long

# Data_Vara <-                          # pivot_longer() only in development version of tidyr... dont use now
#   Data_Season %>%                     # devtools::install_github("tidyverse/tidyr")
#   tidyr::pivot_longer(
#     -c(1:5),
#     #cols = starts_with("Ano"), 
#     names_to = c(".value", "var"), 
#     names_sep = "_", 
#     values_drop_na = TRUE
#   )

Data_Season_melt <-                         
  Data_Season %>%
  gather(variable, value, -c(1:5)) %>%
  mutate(group = readr::parse_number(variable)) %>%
  mutate(variable = gsub("\\d","",x = variable)) %>%
  spread(variable, value) %>%
  rename_all(~stringr::str_replace_all(., "_", "")) %>%           # delete the "_" at end
  mutate(Ano = factor(Ano, levels = c("Vara", "Primavara", "Toamna", "Iarna"))) %>%
  mutate_at(vars("Relv", "Val", "Varstaamin", "Viv"), funs(as.numeric(as.character(.))))
  
## Season data frames
# Data_Vara <-
#   Data_Season_melt %>%
#   filter(!is.na(Ano)) %>%                # delete rows were there is no Ano
#   filter(Ano == "Vara")
# 
# Data_Primavara <-
#   Data_Season_melt %>%
#   filter(!is.na(Ano)) %>%                # delete rows were there is no Ano
#   filter(Ano == "Primavara")
# 
# Data_Toamna <-
#   Data_Season_melt %>%
#   filter(!is.na(Ano)) %>%                # delete rows were there is no Ano
#   filter(Ano == "Toamna")
# 
# Data_Iarna <-
#   Data_Season_melt %>%
#   filter(!is.na(Ano)) %>%                # delete rows were there is no Ano
#   filter(Ano == "Iarna")
# 
# 
# ## Excel downloadable DT tables
# Data_Vara %>%                              
#   select(-Nume) %>%
#     DT::datatable(                                  
#       extensions = 'Buttons',
#       options = list(pageLength = 10,
#                      scrollX='500px', 
#                      dom = 'Bfrtip', 
#                      buttons = c('excel', "csv")))
# 
# Data_Primavara %>%                              
#   select(-Nume) %>%
#     DT::datatable(                                  
#       extensions = 'Buttons',
#       options = list(pageLength = 10,
#                      scrollX='500px', 
#                      dom = 'Bfrtip', 
#                      buttons = c('excel', "csv")))
# 
# Data_Toamna %>%                              
#   select(-Nume) %>%
#     DT::datatable(                                  
#       extensions = 'Buttons',
#       options = list(pageLength = 10,
#                      scrollX='500px', 
#                      dom = 'Bfrtip', 
#                      buttons = c('excel', "csv")))
# 
# Data_Iarna %>%                              
#   select(-Nume) %>%
#     DT::datatable(                                  
#       extensions = 'Buttons',
#       options = list(pageLength = 10,
#                      scrollX='500px', 
#                      dom = 'Bfrtip', 
#                      buttons = c('excel', "csv")))


cat("### Melt to Long Format")

3.1.1 Melt to Long Format

3.1.2 Wide Format

3.1.3 Wide Format for Ano ~ Valence

3.2 Define Function for Plots

## Function for Ano Bar Plot
my_comparisons <- 
  gtools::combinations(n = length(unique(Data_Season_melt_nona$Ano)), r = 2, v = as.character(Data_Season_melt_nona$Ano), repeats.allowed = FALSE) %>%
  as.data.frame() %>% 
  mutate_if(is.factor, as.character) %>%
  purrr::pmap(list) %>% 
  lapply(unlist)

func_plot_ano <- function(df, y_var, y_var_lab, label.y_set = 7, yticks.by_set = 1, facet = FALSE){
  if(facet){
    facet <- "Protocol"
  }else{
    facet <- NULL
  }
  p <-
    df  %>%
    ggpubr::ggbarplot(x = "Ano", y = y_var, 
                      add = "mean_se",
                      color = "black", fill = "lightgray",
                      xlab = "Anotimp", ylab = y_var_lab,
                      label = TRUE, lab.nb.digits = 2, lab.pos= "in",
                      facet.by = facet) +
    stat_compare_means(method = "anova",
                       label.x = 0.9, label.y = label.y_set) +
    stat_compare_means(comparisons = my_comparisons,
                       label = "p.signif", method = "t.test", paired = FALSE, na.rm = TRUE) 
  ggpar(p, yticks.by = yticks.by_set)                                     # the rating scale is 1-7
}


## Dodged 
func_dodged_ano <- function(df, y_var, y_var_lab, facet = FALSE){
  y_var<- sym(y_var)
  
  if(facet) {
    df <- 
      df %>% 
      mutate(Protocol = paste0("Protocol ", Protocol)) %>%
      group_by(Protocol)  
  }
  
  p <-
    df  %>%
    dplyr::count(Ano, !!y_var) %>%                        # Group by, then count number in each group
    mutate(pct = prop.table(n)) %>%                     # Calculate percent within each var
    mutate(Val_fac = as.factor(!!y_var)) %>%
    ggplot(aes(x = Ano, y = pct, fill = Val_fac, label = scales::percent(pct))) + 
      geom_col(position = 'dodge') + 
      geom_text(position = position_dodge(width = .9),    # move to center of bars
                vjust = -0.5,                             # nudge above top of bar
                size = 3) + 
      scale_y_continuous(labels = scales::percent) +
      {if(facet) facet_wrap(~Protocol, scales = "free", ncol = 1, nrow = 8)} +
      ggtitle(y_var_lab) +
      xlab("Anotimp") + ylab("Percentage %") + 
      guides(fill = guide_legend(title = "Value", nrow = 1)) + 
      scale_fill_grey(start = 0.8, end = 0.2, na.value = "red", aesthetics = "fill") +
      theme(legend.position = "bottom", legend.direction = "horizontal", 
            legend.justification = c(0, 1), panel.border = element_rect(fill = NA, colour = "black"))
  p
}  

3.5 Plots with proportion of values

3.7 Likert Plots for Season

3.7.1 Proportions - compared to 0.5 probability

3.7.2 Proportions - Multiple comparisons

3.7.2.1 Pairwise comparisons using Pairwise comparison of proportions

3.7.2.2 Pairwise comparisons using Pairwise comparison of proportions (Fisher exact)

4 Session Info

R version 3.6.1 (2019-07-05)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 8.1 x64 (build 9600)

Matrix products: default

locale:
[1] LC_COLLATE=Romanian_Romania.1250  LC_CTYPE=Romanian_Romania.1250    LC_MONETARY=Romanian_Romania.1250 LC_NUMERIC=C                     
[5] LC_TIME=Romanian_Romania.1250    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] likert_1.3.5               xtable_1.8-4               fmsb_0.6.3                 rio_0.5.16                 scales_1.0.0              
 [6] ggpubr_0.2                 magrittr_1.5               tadaatoolbox_0.16.1        summarytools_0.8.8         rstatix_0.2.0             
[11] broom_0.5.2                PerformanceAnalytics_1.5.2 xts_0.11-2                 zoo_1.8-4                  psych_1.8.12              
[16] plyr_1.8.4                 forcats_0.4.0              stringr_1.4.0              dplyr_0.8.3                purrr_0.3.2               
[21] readr_1.3.1                tidyr_1.0.0                tibble_2.1.3               ggplot2_3.2.1              tidyverse_1.2.1           
[26] papaja_0.1.0.9842          pacman_0.5.1              

loaded via a namespace (and not attached):
 [1] colorspace_1.4-1   ggsignif_0.4.0     pryr_0.1.4         ellipsis_0.3.0     rstudioapi_0.8     DT_0.5             mvtnorm_1.0-11    
 [8] lubridate_1.7.4    xml2_1.2.0         codetools_0.2-16   mnormt_1.5-5       knitr_1.25         zeallot_0.1.0      pixiedust_0.8.6   
[15] jsonlite_1.6       shiny_1.2.0        compiler_3.6.1     httr_1.4.0         backports_1.1.4    assertthat_0.2.1   Matrix_1.2-17     
[22] lazyeval_0.2.2     cli_1.1.0          later_0.7.5        htmltools_0.3.6    tools_3.6.1        gtable_0.3.0       glue_1.3.1        
[29] reshape2_1.4.3     Rcpp_1.0.2         carData_3.0-2      cellranger_1.1.0   vctrs_0.2.0        nlme_3.1-140       crosstalk_1.0.0   
[36] xfun_0.9           openxlsx_4.1.0     rvest_0.3.2        mime_0.7           lifecycle_0.1.0    gtools_3.8.1       MASS_7.3-51.4     
[43] hms_0.5.1          promises_1.0.1     parallel_3.6.1     expm_0.999-3       pwr_1.2-2          yaml_2.2.0         curl_3.2          
[50] gridExtra_2.3      pander_0.6.3       stringi_1.4.3      nortest_1.0-4      boot_1.3-22        zip_1.0.0          rlang_0.4.0       
[57] pkgconfig_2.0.3    matrixStats_0.54.0 bitops_1.0-6       lattice_0.20-38    labeling_0.3       rapportools_1.0    htmlwidgets_1.3   
[64] tidyselect_0.2.5   ggsci_2.9          R6_2.4.0           DescTools_0.99.29  generics_0.0.2     pillar_1.4.2       haven_2.1.1       
[71] foreign_0.8-71     withr_2.1.2        abind_1.4-5        RCurl_1.95-4.11    modelr_0.1.5       crayon_1.3.4       car_3.0-2         
[78] viridis_0.5.1      grid_3.6.1         readxl_1.1.0       data.table_1.11.8  digest_0.6.21      httpuv_1.4.5       munsell_0.5.0     
[85] viridisLite_0.3.0  quadprog_1.5-5    
 

A work by Claudiu Papasteri

 

LS0tDQp0aXRsZTogIjxicj4gQW5hbHlzZXMgZm9yIE0uMS4gKEF1dG9iaW9ncmFwaGljYWwgTWVtb3JpZXMpIiANCnN1YnRpdGxlOiAiRm9jdXMgb24gU2Vhc29ucyAtIGluZGl2aWR1YWwgc3RpbXVsaSINCmF1dGhvcjogIjxicj4gQ2xhdWRpdSBQYXBhc3RlcmkiDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlbSAlWScpYCINCm91dHB1dDogDQogICAgaHRtbF9ub3RlYm9vazoNCiAgICAgICAgICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgICAgICAgICAgdG9jOiB0cnVlDQogICAgICAgICAgICB0b2NfZGVwdGg6IDINCiAgICAgICAgICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQ0KICAgICAgICAgICAgdGhlbWU6IHNwYWNlbGFiDQogICAgICAgICAgICBoaWdobGlnaHQ6IHRhbmdvDQogICAgICAgICAgICBmb250LWZhbWlseTogQXJpYWwNCiAgICAgICAgICAgIGZpZ193aWR0aDogMTANCiAgICAgICAgICAgIGZpZ19oZWlnaHQ6IDkNCiAgICAjIHdvcmRfZG9jdW1lbnQgICAgICAgIA0KICAgICMgcGRmX2RvY3VtZW50OiANCiAgICAgICAgICAgICMgdG9jOiB0cnVlDQogICAgICAgICAgICAjIHRvY19kZXB0aDogMg0KICAgICAgICAgICAgIyBudW1iZXJfc2VjdGlvbnM6IHRydWUNCiAgICAgICAgICAgICMgZm9udHNpemU6IDExcHQNCiAgICAgICAgICAgICMgZ2VvbWV0cnk6IG1hcmdpbj0xaW4NCiAgICAgICAgICAgICMgZmlnX3dpZHRoOiA3DQogICAgICAgICAgICAjIGZpZ19oZWlnaHQ6IDYNCiAgICAgICAgICAgICMgZmlnX2NhcHRpb246IHRydWUNCiAgICAjIGdpdGh1Yl9kb2N1bWVudDogDQogICAgICAgICAgICAjIHRvYzogdHJ1ZQ0KICAgICAgICAgICAgIyB0b2NfZGVwdGg6IDINCiAgICAgICAgICAgICMgaHRtbF9wcmV2aWV3OiBmYWxzZQ0KICAgICAgICAgICAgIyBmaWdfd2lkdGg6IDUNCiAgICAgICAgICAgICMgZmlnX2hlaWdodDogNQ0KICAgICAgICAgICAgIyBkZXY6IGpwZWcNCi0tLQ0KDQoNCjwhLS0gU2V0dXAgLS0+DQoNCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQojIGtpbnRyIG9wdGlvbnMNCmtuaXRyOjpvcHRzX2NodW5rJHNldCgNCiAgY29tbWVudCA9ICIjIiwNCiAgY29sbGFwc2UgPSBUUlVFLA0KICBlY2hvID0gVFJVRSwgDQogIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFLCBlcnJvciA9IEZBTFNFLA0KICBjYWNoZSA9IFRSVUUgICAgICAgIyBlY2hvID0gRmFsc2UgZm9yIGdpdGh1Yl9kb2N1bWVudCwgYnV0IHdpbGwgYmUgZm9sZGVkIGluIGh0bWxfbm90ZWJvb2sNCikNCg0KIyBHZW5lcmFsIFIgb3B0aW9ucyBhbmQgaW5mbw0Kc2V0LnNlZWQoMTExKSAgICAgICAgICAgICAgICMgaW4gY2FzZSB3ZSB1c2UgcmFuZG9taXplZCBwcm9jZWR1cmVzICAgICAgIA0Kb3B0aW9ucyhzY2lwZW4gPSA5OTkpICAgICAgICMgcG9zaXRpdmUgdmFsdWVzIGJpYXMgdG93YXJkcyBmaXhlZCBhbmQgbmVnYXRpdmUgdG93YXJkcyBzY2llbnRpZmljIG5vdGF0aW9uDQoNCiMgTG9hZCBwYWNrYWdlcw0KaWYgKCFyZXF1aXJlKCJwYWNtYW4iKSkgaW5zdGFsbC5wYWNrYWdlcygicGFjbWFuIikNCnBhY2thZ2VzIDwtIGMoDQogICJwYXBhamEiLA0KICAidGlkeXZlcnNlIiwgInBseXIiLCAgICAgIA0KICAicHN5Y2giLCAiUGVyZm9ybWFuY2VBbmFseXRpY3MiLCAgICAgICAgICANCiAgImJyb29tIiwgInJzdGF0aXgiLA0KICAic3VtbWFyeXRvb2xzIiwgInRhZGFhdG9vbGJveCIsICAgICAgICAgICANCiAgImdncGxvdDIiLCAiZ2dwdWJyIiwgInNjYWxlcyIsICAgICAgICANCiAgInJpbyIsDQogICJmbXNiIiwgImxpa2VydCINCiAgIyAsIC4uLg0KKQ0KaWYgKCFyZXF1aXJlKCJwYWNtYW4iKSkgaW5zdGFsbC5wYWNrYWdlcygicGFjbWFuIikNCnBhY21hbjo6cF9sb2FkKGNoYXIgPSBwYWNrYWdlcykNCg0KIyBUaGVtZXMgZm9yIGdncGxvdDIgcGxvdGluZyAoaGVyZSB1c2VkIEFQQSBzdHlsZSkNCnRoZW1lX3NldCh0aGVtZV9hcGEoKSkNCg0KDQojIFRhYmxlcyBrbml0dGluZyB0byBXb3JkDQpkb2MudHlwZSA8LSBrbml0cjo6b3B0c19rbml0JGdldCgncm1hcmtkb3duLnBhbmRvYy50bycpICAjIHRoZW4gZm9ybWF0IHRhYmxlcyB1c2luZyBhbiBpZiBzdGF0ZW1lbnQgbGlrZToNCiMgaWYgKGRvYy50eXBlID09ICJkb2N4IikgeyBwYW5kZXI6OnBhbmRlcihkZikgfSBlbHNlIHsga25pdHI6OmthYmxlKGRmKSB9DQpgYGANCg0KDQoNCg0KDQo8IS0tIFJlcG9ydCAtLT4NCg0KDQojIFJlYWQsIENsZWFuLCBSZWNvZGUsIE1lcmdlDQoNCmBgYHtyIHJlZF9jbGVhbl9yZWNvZGVfbWVyZ2UsIHJlc3VsdHM9J2hpZGUnfQ0KI35+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn4NCiMgUmVhZA0KI35+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn4NCg0KIyMgUmVhZCBmaWxlcw0KZm9sZGVyIDwtICJFOi9DaW5ldGljIGlkZWkgbm9pL0NpbmV0aWMgZWxldmkiDQpmaWxlIDwtICJNMSBkZSBpbnRyb2R1cyBhbm90aW1wdXJpLnhsc3giDQoNCnNldHdkKGZvbGRlcikNCkRhdGEgPC0gcmlvOjppbXBvcnQoZmlsZS5wYXRoKGZvbGRlciwgZmlsZSkpDQoNCiMjIFJlY29kZSBOQQ0KRGF0YSA8LSANCiAgRGF0YSAlPiUgICAgICAgICAgICAgIyBzdW0oaXMubmEoRGF0YSkpID0gNTg3Mw0KICBuYV9pZigibmEiKSAgICAgICAgICAjIHN1bShpcy5uYShEYXRhKSkgPSA2MTk5DQoNCg0KIyMgVmFyaWFibGUgbmFtZXMNCm51bWUgPC0gYygiU3RpbSIsICJWYXJzdGFfYW1pbiIsICJBbm8iLCAiVmFsIiwgIlZpdiIsICJSZWx2IikNCnRvYXRlIDwtIHBhc3RlKG51bWUsIHJlcCgxOjE1LCBlYWNoID0gbGVuZ3RoKG51bWUpKSwgc2VwID0gIl8iKQ0KDQojIyBDaGVjayB0aGF0IGFsbCB2YXJpYWJsZSBuYW1lcyBhcmUgY29uc2lzdGVudCB3aXRoIGNvbHVtbiBoZWFkZXJzDQppZih0b2F0ZSAlaW4lIG5hbWVzKERhdGEpKXsNCiAgY2F0KCJBbGwgY29sdW1uIG5hbWVzIGFyZSBjb25zaXN0ZW50LiIpDQp9IGVsc2Ugew0KICBjYXQoIkNvbHVtbiBuYW1lcyBhcmUgTk9UIGNvbnNpc3RlbnQuIFxuIikNCiAgY2F0KCJNaXNzbWF0Y2hlczogXG4gIikNCiAgc2V0ZGlmZih0b2F0ZSwgbmFtZXMoRGF0YSkpDQp9DQpgYGANCg0KDQojIFNhbXBsZSBkZXNjcmlwdGl2ZXMNCg0KYGBge3Igc2FtcGxlX2Rlc2N9DQpjYXQoIiMjIE51bWJlciBvZiBzdWJqZWN0cyIpDQpEYXRhICU+JSANCiBkcGx5cjo6c3VtbWFyaXNlKGNvdW50ID0gZHBseXI6Om5fZGlzdGluY3QoSUQpKQ0KDQpjYXQoIiMjIE51bWJlciBvZiBzdWJqZWN0cyBwZXIgUHJvdG9jb2wiKQ0KRGF0YSAlPiUNCiBncm91cF9ieShQcm90b2NvbCkgJT4lDQogZHBseXI6OnN1bW1hcmlzZShjb3VudCA9IGRwbHlyOjpuX2Rpc3RpbmN0KElEKSkNCmBgYA0KDQoNCiMgU2Vhc29uIE1lbW9yaWVzIGFuZCBWYWxlbmNlDQoNCiMjIE1ha2UgZGF0YSBmcmFtZXMNCg0KYGBge3IgZGZfc2VhbnNvbiwgcmVzdWx0cz0nYXNpcycsIHdhcm5pbmc9RkFMU0V9DQojIyBFeGNsdWRlIFA2ICYgUDcNCkRhdGFfU2Vhc29uIDwtIA0KICBEYXRhICU+JQ0KICBkcGx5cjo6ZmlsdGVyKCFQcm90b2NvbCAlaW4lIGMoNiwgNykpDQoNCiMjIE1lbHQgdG8gTG9uZw0KDQojIERhdGFfVmFyYSA8LSAgICAgICAgICAgICAgICAgICAgICAgICAgIyBwaXZvdF9sb25nZXIoKSBvbmx5IGluIGRldmVsb3BtZW50IHZlcnNpb24gb2YgdGlkeXIuLi4gZG9udCB1c2Ugbm93DQojICAgRGF0YV9TZWFzb24gJT4lICAgICAgICAgICAgICAgICAgICAgIyBkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoInRpZHl2ZXJzZS90aWR5ciIpDQojICAgdGlkeXI6OnBpdm90X2xvbmdlcigNCiMgICAgIC1jKDE6NSksDQojICAgICAjY29scyA9IHN0YXJ0c193aXRoKCJBbm8iKSwgDQojICAgICBuYW1lc190byA9IGMoIi52YWx1ZSIsICJ2YXIiKSwgDQojICAgICBuYW1lc19zZXAgPSAiXyIsIA0KIyAgICAgdmFsdWVzX2Ryb3BfbmEgPSBUUlVFDQojICAgKQ0KDQpEYXRhX1NlYXNvbl9tZWx0IDwtICAgICAgICAgICAgICAgICAgICAgICAgIA0KICBEYXRhX1NlYXNvbiAlPiUNCiAgZ2F0aGVyKHZhcmlhYmxlLCB2YWx1ZSwgLWMoMTo1KSkgJT4lDQogIG11dGF0ZShncm91cCA9IHJlYWRyOjpwYXJzZV9udW1iZXIodmFyaWFibGUpKSAlPiUNCiAgbXV0YXRlKHZhcmlhYmxlID0gZ3N1YigiXFxkIiwiIix4ID0gdmFyaWFibGUpKSAlPiUNCiAgc3ByZWFkKHZhcmlhYmxlLCB2YWx1ZSkgJT4lDQogIHJlbmFtZV9hbGwofnN0cmluZ3I6OnN0cl9yZXBsYWNlX2FsbCguLCAiXyIsICIiKSkgJT4lICAgICAgICAgICAjIGRlbGV0ZSB0aGUgIl8iIGF0IGVuZA0KICBtdXRhdGUoQW5vID0gZmFjdG9yKEFubywgbGV2ZWxzID0gYygiVmFyYSIsICJQcmltYXZhcmEiLCAiVG9hbW5hIiwgIklhcm5hIikpKSAlPiUNCiAgbXV0YXRlX2F0KHZhcnMoIlJlbHYiLCAiVmFsIiwgIlZhcnN0YWFtaW4iLCAiVml2IiksIGZ1bnMoYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoLikpKSkNCiAgDQojIyBTZWFzb24gZGF0YSBmcmFtZXMNCiMgRGF0YV9WYXJhIDwtDQojICAgRGF0YV9TZWFzb25fbWVsdCAlPiUNCiMgICBmaWx0ZXIoIWlzLm5hKEFubykpICU+JSAgICAgICAgICAgICAgICAjIGRlbGV0ZSByb3dzIHdlcmUgdGhlcmUgaXMgbm8gQW5vDQojICAgZmlsdGVyKEFubyA9PSAiVmFyYSIpDQojIA0KIyBEYXRhX1ByaW1hdmFyYSA8LQ0KIyAgIERhdGFfU2Vhc29uX21lbHQgJT4lDQojICAgZmlsdGVyKCFpcy5uYShBbm8pKSAlPiUgICAgICAgICAgICAgICAgIyBkZWxldGUgcm93cyB3ZXJlIHRoZXJlIGlzIG5vIEFubw0KIyAgIGZpbHRlcihBbm8gPT0gIlByaW1hdmFyYSIpDQojIA0KIyBEYXRhX1RvYW1uYSA8LQ0KIyAgIERhdGFfU2Vhc29uX21lbHQgJT4lDQojICAgZmlsdGVyKCFpcy5uYShBbm8pKSAlPiUgICAgICAgICAgICAgICAgIyBkZWxldGUgcm93cyB3ZXJlIHRoZXJlIGlzIG5vIEFubw0KIyAgIGZpbHRlcihBbm8gPT0gIlRvYW1uYSIpDQojIA0KIyBEYXRhX0lhcm5hIDwtDQojICAgRGF0YV9TZWFzb25fbWVsdCAlPiUNCiMgICBmaWx0ZXIoIWlzLm5hKEFubykpICU+JSAgICAgICAgICAgICAgICAjIGRlbGV0ZSByb3dzIHdlcmUgdGhlcmUgaXMgbm8gQW5vDQojICAgZmlsdGVyKEFubyA9PSAiSWFybmEiKQ0KIyANCiMgDQojICMjIEV4Y2VsIGRvd25sb2FkYWJsZSBEVCB0YWJsZXMNCiMgRGF0YV9WYXJhICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KIyAgIHNlbGVjdCgtTnVtZSkgJT4lDQojICAgICBEVDo6ZGF0YXRhYmxlKCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiMgICAgICAgZXh0ZW5zaW9ucyA9ICdCdXR0b25zJywNCiMgICAgICAgb3B0aW9ucyA9IGxpc3QocGFnZUxlbmd0aCA9IDEwLA0KIyAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxYPSc1MDBweCcsIA0KIyAgICAgICAgICAgICAgICAgICAgICBkb20gPSAnQmZydGlwJywgDQojICAgICAgICAgICAgICAgICAgICAgIGJ1dHRvbnMgPSBjKCdleGNlbCcsICJjc3YiKSkpDQojIA0KIyBEYXRhX1ByaW1hdmFyYSAlPiUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiMgICBzZWxlY3QoLU51bWUpICU+JQ0KIyAgICAgRFQ6OmRhdGF0YWJsZSggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQojICAgICAgIGV4dGVuc2lvbnMgPSAnQnV0dG9ucycsDQojICAgICAgIG9wdGlvbnMgPSBsaXN0KHBhZ2VMZW5ndGggPSAxMCwNCiMgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsWD0nNTAwcHgnLCANCiMgICAgICAgICAgICAgICAgICAgICAgZG9tID0gJ0JmcnRpcCcsIA0KIyAgICAgICAgICAgICAgICAgICAgICBidXR0b25zID0gYygnZXhjZWwnLCAiY3N2IikpKQ0KIyANCiMgRGF0YV9Ub2FtbmEgJT4lICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQojICAgc2VsZWN0KC1OdW1lKSAlPiUNCiMgICAgIERUOjpkYXRhdGFibGUoICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KIyAgICAgICBleHRlbnNpb25zID0gJ0J1dHRvbnMnLA0KIyAgICAgICBvcHRpb25zID0gbGlzdChwYWdlTGVuZ3RoID0gMTAsDQojICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbFg9JzUwMHB4JywgDQojICAgICAgICAgICAgICAgICAgICAgIGRvbSA9ICdCZnJ0aXAnLCANCiMgICAgICAgICAgICAgICAgICAgICAgYnV0dG9ucyA9IGMoJ2V4Y2VsJywgImNzdiIpKSkNCiMgDQojIERhdGFfSWFybmEgJT4lICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQojICAgc2VsZWN0KC1OdW1lKSAlPiUNCiMgICAgIERUOjpkYXRhdGFibGUoICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KIyAgICAgICBleHRlbnNpb25zID0gJ0J1dHRvbnMnLA0KIyAgICAgICBvcHRpb25zID0gbGlzdChwYWdlTGVuZ3RoID0gMTAsDQojICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbFg9JzUwMHB4JywgDQojICAgICAgICAgICAgICAgICAgICAgIGRvbSA9ICdCZnJ0aXAnLCANCiMgICAgICAgICAgICAgICAgICAgICAgYnV0dG9ucyA9IGMoJ2V4Y2VsJywgImNzdiIpKSkNCg0KDQpjYXQoIiMjIyBNZWx0IHRvIExvbmcgRm9ybWF0IikNCkRhdGFfU2Vhc29uX21lbHQgJT4lDQogIGRwbHlyOjpzZWxlY3QoLU51bWUpICU+JQ0KICAgIERUOjpkYXRhdGFibGUoDQogICAgICBleHRlbnNpb25zID0gJ0J1dHRvbnMnLA0KICAgICAgb3B0aW9ucyA9IGxpc3QocGFnZUxlbmd0aCA9IDEwLA0KICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsWD0nNTAwcHgnLA0KICAgICAgICAgICAgICAgICAgICAgZG9tID0gJ0JmcnRpcCcsDQogICAgICAgICAgICAgICAgICAgICBidXR0b25zID0gYygnZXhjZWwnLCAiY3N2IikpKQ0KDQpjYXQoIiMjIyBXaWRlIEZvcm1hdCIpDQpEYXRhX1NlYXNvbiAlPiUNCiAgZHBseXI6OnNlbGVjdCgtTnVtZSkgJT4lDQogICAgRFQ6OmRhdGF0YWJsZSgNCiAgICAgIGV4dGVuc2lvbnMgPSAnQnV0dG9ucycsDQogICAgICBvcHRpb25zID0gbGlzdChwYWdlTGVuZ3RoID0gMTAsDQogICAgICAgICAgICAgICAgICAgICBzY3JvbGxYPSc1MDBweCcsDQogICAgICAgICAgICAgICAgICAgICBkb20gPSAnQmZydGlwJywNCiAgICAgICAgICAgICAgICAgICAgIGJ1dHRvbnMgPSBjKCdleGNlbCcsICJjc3YiKSkpDQoNCg0KIyMgRGF0YSBGcmFtZSBmb3IgUGxvdHMNCkRhdGFfU2Vhc29uX21lbHRfbm9uYSA8LQ0KICBEYXRhX1NlYXNvbl9tZWx0ICU+JQ0KICBmaWx0ZXIoIWlzLm5hKEFubykpDQoNCg0KY2F0KCIjIyMgV2lkZSBGb3JtYXQgZm9yIEFubyB+IFZhbGVuY2UiKQ0KRGF0YV9TZWFzb25fbWVsdF9ub25hICU+JQ0KICBkcGx5cjo6c2VsZWN0KElELCBBbm8sIFZhbCkgJT4lDQogIHJvd25hbWVzX3RvX2NvbHVtbigpICU+JQ0KICBzcHJlYWQoa2V5ID0gQW5vLCB2YWx1ZSA9IFZhbCkgJT4lDQogIGFycmFuZ2UoSUQpICU+JQ0KICAgIERUOjpkYXRhdGFibGUoDQogICAgICBleHRlbnNpb25zID0gJ0J1dHRvbnMnLA0KICAgICAgb3B0aW9ucyA9IGxpc3QocGFnZUxlbmd0aCA9IDEwLA0KICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsWD0nNTAwcHgnLA0KICAgICAgICAgICAgICAgICAgICAgZG9tID0gJ0JmcnRpcCcsDQogICAgICAgICAgICAgICAgICAgICBidXR0b25zID0gYygnZXhjZWwnLCAiY3N2IikpKQ0KYGBgDQoNCg0KIyMgRGVmaW5lIEZ1bmN0aW9uIGZvciBQbG90cw0KDQpgYGB7ciBkZWZfZnVuY19wbG90fQ0KIyMgRnVuY3Rpb24gZm9yIEFubyBCYXIgUGxvdA0KbXlfY29tcGFyaXNvbnMgPC0gDQogIGd0b29sczo6Y29tYmluYXRpb25zKG4gPSBsZW5ndGgodW5pcXVlKERhdGFfU2Vhc29uX21lbHRfbm9uYSRBbm8pKSwgciA9IDIsIHYgPSBhcy5jaGFyYWN0ZXIoRGF0YV9TZWFzb25fbWVsdF9ub25hJEFubyksIHJlcGVhdHMuYWxsb3dlZCA9IEZBTFNFKSAlPiUNCiAgYXMuZGF0YS5mcmFtZSgpICU+JSANCiAgbXV0YXRlX2lmKGlzLmZhY3RvciwgYXMuY2hhcmFjdGVyKSAlPiUNCiAgcHVycnI6OnBtYXAobGlzdCkgJT4lIA0KICBsYXBwbHkodW5saXN0KQ0KDQpmdW5jX3Bsb3RfYW5vIDwtIGZ1bmN0aW9uKGRmLCB5X3ZhciwgeV92YXJfbGFiLCBsYWJlbC55X3NldCA9IDcsIHl0aWNrcy5ieV9zZXQgPSAxLCBmYWNldCA9IEZBTFNFKXsNCiAgaWYoZmFjZXQpew0KICAgIGZhY2V0IDwtICJQcm90b2NvbCINCiAgfWVsc2V7DQogICAgZmFjZXQgPC0gTlVMTA0KICB9DQogIHAgPC0NCiAgICBkZiAgJT4lDQogICAgZ2dwdWJyOjpnZ2JhcnBsb3QoeCA9ICJBbm8iLCB5ID0geV92YXIsIA0KICAgICAgICAgICAgICAgICAgICAgIGFkZCA9ICJtZWFuX3NlIiwNCiAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIsIGZpbGwgPSAibGlnaHRncmF5IiwNCiAgICAgICAgICAgICAgICAgICAgICB4bGFiID0gIkFub3RpbXAiLCB5bGFiID0geV92YXJfbGFiLA0KICAgICAgICAgICAgICAgICAgICAgIGxhYmVsID0gVFJVRSwgbGFiLm5iLmRpZ2l0cyA9IDIsIGxhYi5wb3M9ICJpbiIsDQogICAgICAgICAgICAgICAgICAgICAgZmFjZXQuYnkgPSBmYWNldCkgKw0KICAgIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAiYW5vdmEiLA0KICAgICAgICAgICAgICAgICAgICAgICBsYWJlbC54ID0gMC45LCBsYWJlbC55ID0gbGFiZWwueV9zZXQpICsNCiAgICBzdGF0X2NvbXBhcmVfbWVhbnMoY29tcGFyaXNvbnMgPSBteV9jb21wYXJpc29ucywNCiAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAicC5zaWduaWYiLCBtZXRob2QgPSAidC50ZXN0IiwgcGFpcmVkID0gRkFMU0UsIG5hLnJtID0gVFJVRSkgDQogIGdncGFyKHAsIHl0aWNrcy5ieSA9IHl0aWNrcy5ieV9zZXQpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgdGhlIHJhdGluZyBzY2FsZSBpcyAxLTcNCn0NCg0KDQojIyBEb2RnZWQgDQpmdW5jX2RvZGdlZF9hbm8gPC0gZnVuY3Rpb24oZGYsIHlfdmFyLCB5X3Zhcl9sYWIsIGZhY2V0ID0gRkFMU0Upew0KICB5X3ZhcjwtIHN5bSh5X3ZhcikNCiAgDQogIGlmKGZhY2V0KSB7DQogICAgZGYgPC0gDQogICAgICBkZiAlPiUgDQogICAgICBtdXRhdGUoUHJvdG9jb2wgPSBwYXN0ZTAoIlByb3RvY29sICIsIFByb3RvY29sKSkgJT4lDQogICAgICBncm91cF9ieShQcm90b2NvbCkgIA0KICB9DQogIA0KICBwIDwtDQogICAgZGYgICU+JQ0KICAgIGRwbHlyOjpjb3VudChBbm8sICEheV92YXIpICU+JSAgICAgICAgICAgICAgICAgICAgICAgICMgR3JvdXAgYnksIHRoZW4gY291bnQgbnVtYmVyIGluIGVhY2ggZ3JvdXANCiAgICBtdXRhdGUocGN0ID0gcHJvcC50YWJsZShuKSkgJT4lICAgICAgICAgICAgICAgICAgICAgIyBDYWxjdWxhdGUgcGVyY2VudCB3aXRoaW4gZWFjaCB2YXINCiAgICBtdXRhdGUoVmFsX2ZhYyA9IGFzLmZhY3RvcighIXlfdmFyKSkgJT4lDQogICAgZ2dwbG90KGFlcyh4ID0gQW5vLCB5ID0gcGN0LCBmaWxsID0gVmFsX2ZhYywgbGFiZWwgPSBzY2FsZXM6OnBlcmNlbnQocGN0KSkpICsgDQogICAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICdkb2RnZScpICsgDQogICAgICBnZW9tX3RleHQocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IC45KSwgICAgIyBtb3ZlIHRvIGNlbnRlciBvZiBiYXJzDQogICAgICAgICAgICAgICAgdmp1c3QgPSAtMC41LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBudWRnZSBhYm92ZSB0b3Agb2YgYmFyDQogICAgICAgICAgICAgICAgc2l6ZSA9IDMpICsgDQogICAgICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50KSArDQogICAgICB7aWYoZmFjZXQpIGZhY2V0X3dyYXAoflByb3RvY29sLCBzY2FsZXMgPSAiZnJlZSIsIG5jb2wgPSAxLCBucm93ID0gOCl9ICsNCiAgICAgIGdndGl0bGUoeV92YXJfbGFiKSArDQogICAgICB4bGFiKCJBbm90aW1wIikgKyB5bGFiKCJQZXJjZW50YWdlICUiKSArIA0KICAgICAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQodGl0bGUgPSAiVmFsdWUiLCBucm93ID0gMSkpICsgDQogICAgICBzY2FsZV9maWxsX2dyZXkoc3RhcnQgPSAwLjgsIGVuZCA9IDAuMiwgbmEudmFsdWUgPSAicmVkIiwgYWVzdGhldGljcyA9ICJmaWxsIikgKw0KICAgICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsIGxlZ2VuZC5kaXJlY3Rpb24gPSAiaG9yaXpvbnRhbCIsIA0KICAgICAgICAgICAgbGVnZW5kLmp1c3RpZmljYXRpb24gPSBjKDAsIDEpLCBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoZmlsbCA9IE5BLCBjb2xvdXIgPSAiYmxhY2siKSkNCiAgcA0KfSAgDQpgYGANCg0KDQoNCiMjIFBsb3RzIG9mIFNlYXNvbnMNCg0KYGBge3IgcGxvdF9zZWFuc29uLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD03LCBmaWcuYWxpZ249J2NlbnRlcid9DQojIyBUZXN0IGZvciBWYWwgLS0gd29ya3Mgd2VsbA0KIyBEYXRhX1NlYXNvbl9tZWx0X25vbmEgICU+JQ0KIyAgIGdncHVicjo6Z2diYXJwbG90KHggPSAiQW5vIiwgeSA9ICJWYWwiLCANCiMgICAgICAgICAgICAgICAgICAgICBhZGQgPSAibWVhbl9zZSIsDQojICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siLCBmaWxsID0gImxpZ2h0Z3JheSIsDQojICAgICAgICAgICAgICAgICAgICAgeGxhYiA9ICJBbm90aW1wIiwgeWxhYiA9ICJWYWxlbnRhIiwNCiMgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IFRSVUUsIGxhYi5uYi5kaWdpdHMgPSAyLCBsYWIucG9zPSAiaW4iKSArDQojICAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJhbm92YSIsDQojICAgICAgICAgICAgICAgICAgICAgIGxhYmVsLnggPSAwLjksIGxhYmVsLnkgPSA3KSArDQojICAgc3RhdF9jb21wYXJlX21lYW5zKGNvbXBhcmlzb25zID0gbXlfY29tcGFyaXNvbnMsDQojICAgICAgICAgICAgICAgICAgICAgIGxhYmVsID0gInAuc2lnbmlmIiwgbWV0aG9kID0gInQudGVzdCIsIHBhaXJlZCA9IEZBTFNFLCBuYS5ybSA9IFRSVUUpIA0KDQoNCmZ1bmNfcGxvdF9hbm8oRGF0YV9TZWFzb25fbWVsdF9ub25hLCAiVmFsIiwgIlZhbGVudGEiKQ0KZnVuY19wbG90X2FubyhEYXRhX1NlYXNvbl9tZWx0X25vbmEsICJSZWx2IiwgIlJlbGV2YW50YSBwZXJzb25hbGEiKQ0KZnVuY19wbG90X2FubyhEYXRhX1NlYXNvbl9tZWx0X25vbmEsICJWaXYiLCAiVml2aWQiKQ0KZnVuY19wbG90X2FubyhEYXRhX1NlYXNvbl9tZWx0X25vbmEsICJWYXJzdGFhbWluIiwgIlZhcnN0YSBhbWludGlyZSIsIGxhYmVsLnlfc2V0ID0gNTAsIHl0aWNrcy5ieV9zZXQgPSA1KQ0KYGBgDQoNCg0KIyMgUGxvdHMgb2YgU2Vhc29ucyBieSBQcm90b2NvbA0KDQpgYGB7ciBwbG90X3NlYW5zb24yLCBmaWcuaGVpZ2h0PTEwLCBmaWcud2lkdGg9MTIsIGZpZy5hbGlnbj0nY2VudGVyJ30NCmZ1bmNfcGxvdF9hbm8oRGF0YV9TZWFzb25fbWVsdF9ub25hLCAiVmFsIiwgIlZhbGVudGEiLCBmYWNldCA9IFRSVUUpIA0KZnVuY19wbG90X2FubyhEYXRhX1NlYXNvbl9tZWx0X25vbmEsICJSZWx2IiwgIlJlbGV2YW50YSBwZXJzb25hbGEiLCBmYWNldCA9IFRSVUUpDQpmdW5jX3Bsb3RfYW5vKERhdGFfU2Vhc29uX21lbHRfbm9uYSwgIlZpdiIsICJWaXZpZCIsIGZhY2V0ID0gVFJVRSkNCmZ1bmNfcGxvdF9hbm8oRGF0YV9TZWFzb25fbWVsdF9ub25hLCAiVmFyc3RhYW1pbiIsICJWYXJzdGEgYW1pbnRpcmUiLCBsYWJlbC55X3NldCA9IDUwLCB5dGlja3MuYnlfc2V0ID0gNSwgZmFjZXQgPSBUUlVFKQ0KYGBgDQoNCg0KIyMgUGxvdHMgd2l0aCBwcm9wb3J0aW9uIG9mIHZhbHVlcw0KDQpgYGB7ciBwbG90X3NlYW5zb25fcHJvcCwgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9MTIsIGZpZy5hbGlnbj0nY2VudGVyJ30NCiMgIyBTdGFja2VkIC0gVGVzdCBmb3IgVmFsIC0tIHdvcmtzIHdlbGwNCiMgRGF0YV9TZWFzb25fbWVsdF9ub25hICU+JSANCiMgICBkcGx5cjo6Y291bnQoQW5vLCBWYWwpICU+JSAgICAgICAgICAgICAgICAgICAjIEdyb3VwIGJ5LCB0aGVuIGNvdW50IG51bWJlciBpbiBlYWNoIGdyb3VwDQojICAgbXV0YXRlKHBjdCA9IG4vc3VtKG4pKSAlPiUgICAgICAgICAgICAgICAgICAgIyBDYWxjdWxhdGUgcGVyY2VudCB3aXRoaW4gZWFjaCB2YXI7IGNvdWxkIHVzZSBwcm9wLnRhYmxlKG4pDQojICAgbXV0YXRlKFZhbF9mYWMgPSBhcy5mYWN0b3IoVmFsKSkgJT4lDQojIGdncGxvdChhZXMoQW5vLCBuLCBmaWxsID0gVmFsX2ZhYykpICsNCiMgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKyAgICAgICAgICAgICAgICAgDQojICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlMChzcHJpbnRmKCIlMS4xZiIsIHBjdCoxMDApLCAiJSIpLCBzaXplID0gc2NhbGVzOjpyZXNjYWxlKHBjdCwgdG89YygyLCA1KSkpLCANCiMgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdD0wLjUpLCBzaG93LmxlZ2VuZCA9IEZBTFNFKQ0KIyANCiMgDQojICMgRG9kZ2VkIC0gVGVzdCBmb3IgVmFsIC0tIHdvcmtzIHdlbGwNCiMgRGF0YV9TZWFzb25fbWVsdF9ub25hICU+JSANCiMgICBkcGx5cjo6Y291bnQoQW5vLCBWYWwpICU+JSAgICAgICAgICAgICAgICAgICAgICAgICMgR3JvdXAgYnksIHRoZW4gY291bnQgbnVtYmVyIGluIGVhY2ggZ3JvdXANCiMgICBtdXRhdGUocGN0ID0gcHJvcC50YWJsZShuKSkgJT4lICAgICAgICAgICAgICAgICAgICMgQ2FsY3VsYXRlIHBlcmNlbnQgd2l0aGluIGVhY2ggdmFyDQojICAgbXV0YXRlKFZhbF9mYWMgPSBhcy5mYWN0b3IoVmFsKSkgJT4lDQojICAgZ2dwbG90KGFlcyh4ID0gQW5vLCB5ID0gcGN0LCBmaWxsID0gVmFsX2ZhYywgbGFiZWwgPSBzY2FsZXM6OnBlcmNlbnQocGN0KSkpICsgDQojICAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICdkb2RnZScpICsgDQojICAgICBnZW9tX3RleHQocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IC45KSwgICAgIyBtb3ZlIHRvIGNlbnRlciBvZiBiYXJzDQojICAgICAgICAgICAgICAgdmp1c3QgPSAtMC41LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBudWRnZSBhYm92ZSB0b3Agb2YgYmFyDQojICAgICAgICAgICAgICAgc2l6ZSA9IDMpICsgDQojICAgICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50KSArDQojICAgICB4bGFiKCJBbm90aW1wIikgKyB5bGFiKCJQZXJjZW50YWdlICUiKSArIA0KIyAgICAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQodGl0bGUgPSAiVmFsdWUiLCBucm93ID0gMSkpICsgDQojICAgICBzY2FsZV9maWxsX2dyZXkoc3RhcnQgPSAwLjgsIGVuZCA9IDAuMiwgbmEudmFsdWUgPSAicmVkIiwgYWVzdGhldGljcyA9ICJmaWxsIikgKw0KIyAgICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsIGxlZ2VuZC5kaXJlY3Rpb24gPSAiaG9yaXpvbnRhbCIsIGxlZ2VuZC5qdXN0aWZpY2F0aW9uID0gYygwLCAxKSkgDQogIA0KDQpmdW5jX2RvZGdlZF9hbm8oRGF0YV9TZWFzb25fbWVsdF9ub25hLCAiVmFsIiwgIlZhbGVudGEiKQ0KZnVuY19kb2RnZWRfYW5vKERhdGFfU2Vhc29uX21lbHRfbm9uYSwgIlJlbHYiLCAiUmVsZXZhbnRhIHBlcnNvbmFsYSIpDQpmdW5jX2RvZGdlZF9hbm8oRGF0YV9TZWFzb25fbWVsdF9ub25hLCAiVml2IiwgIlZpdmlkIikNCmBgYA0KDQoNCiMjIFBsb3RzIHdpdGggcHJvcG9ydGlvbiBvZiB2YWx1ZXMgYnkgUHJvdG9jb2wNCg0KYGBge3IgcGxvdF9zZWFuc29uX3Byb3AyLCBmaWcuaGVpZ2h0PTI1LCBmaWcud2lkdGg9MTAsIGZpZy5hbGlnbj0nY2VudGVyJ30NCmZ1bmNfZG9kZ2VkX2FubyhEYXRhX1NlYXNvbl9tZWx0X25vbmEsICJWYWwiLCAiVmFsZW50YSIsIGZhY2V0ID0gVFJVRSkNCmZ1bmNfZG9kZ2VkX2FubyhEYXRhX1NlYXNvbl9tZWx0X25vbmEsICJSZWx2IiwgIlJlbGV2YW50YSBwZXJzb25hbGEiLCBmYWNldCA9IFRSVUUpDQpmdW5jX2RvZGdlZF9hbm8oRGF0YV9TZWFzb25fbWVsdF9ub25hLCAiVml2IiwgIlZpdmlkIiwgZmFjZXQgPSBUUlVFKQ0KYGBgDQoNCg0KIyMgTGlrZXJ0IFBsb3RzIGZvciBTZWFzb24NCg0KYGBge3IgcGxvdF9saWtlcnQsIHJlc3VsdHM9J2FzaXMnLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD04LCBmaWcuYWxpZ249J2NlbnRlcid9DQojIFByb3BvcnRpb25zIGFuZCB6LXNjb3Jlcw0KUHJvcF92YWwgPC0gDQogIERhdGFfU2Vhc29uX21lbHRfbm9uYSAlPiUNCiAgICBkcGx5cjo6c2VsZWN0KElELCBQcm90b2NvbCwgQW5vLCBWYWwpICU+JQ0KICAgIGdyb3VwX2J5KEFubykgJT4lDQogICAgbXV0YXRlKA0KICAgICAgVmFsID0gYXMuZmFjdG9yKFZhbCksDQogICAgICBWYWwgPSBmb3JjYXRzOjpmY3RfY29sbGFwc2UoVmFsLCBsb3cgPSBjKCIxIiwgIjIiLCAiMyIpLCBuZXV0cmFsID0gIjQiLCBoaWdoID0gYygiNSIsICI2IiwgIjciKSkNCiAgICAgICkgJT4lDQogICAgZHBseXI6OmNvdW50KFZhbCkgJT4lIA0KICAgIG11dGF0ZSh0b3RhbCA9IHN1bShuKSwNCiAgICAgICAgICAgcGVyYyA9IDEwMCpuL3RvdGFsKQ0KDQpjYXQoIiMjIyBQcm9wb3J0aW9ucyAtIGNvbXBhcmVkIHRvIDAuNSBwcm9iYWJpbGl0eSIpDQpQcm9wX3ZhbCAlPiUNCmZpbHRlcihWYWwgPT0gImhpZ2giKSAlPiUNCiAgcm93d2lzZSAlPiUNCiAgbXV0YXRlKHRzdCA9IGxpc3QoYnJvb206OnRpZHkocHJvcC50ZXN0KG4sIHRvdGFsLCBjb25mLmxldmVsID0gMC45NSkpKSkgJT4lDQogIHRpZHlyOjp1bm5lc3QodHN0KQ0KDQpQcm9wX3ZhbCAlPiUNCmZpbHRlcihWYWwgPT0gImxvdyIpICU+JQ0KICByb3d3aXNlICU+JQ0KICBtdXRhdGUodHN0ID0gbGlzdChicm9vbTo6dGlkeShwcm9wLnRlc3QobiwgdG90YWwsIGNvbmYubGV2ZWwgPSAwLjk1KSkpKSAlPiUgDQogIHRpZHlyOjp1bm5lc3QodHN0KQ0KDQoNCmNhdCgiIyMjIFByb3BvcnRpb25zIC0gTXVsdGlwbGUgY29tcGFyaXNvbnMiKQ0KUGFpcl9Db21wX3Byb3BfaGlnaCA8LSAgICAgICAjIGNvbXBhaXJlIGFsbCBwcm9wb3J0aW9ucyBwYWlyd2lzZQ0KICBQcm9wX3ZhbCAlPiUNCiAgZmlsdGVyKFZhbCA9PSAiaGlnaCIpICU+JQ0KICBkcGx5cjo6c2VsZWN0KC1wZXJjKSAlPiUNCiAgdW5pdGUoIkNhdGVnIiwgYygiQW5vIiwgIlZhbCIpLCBzZXAgPSAiLSIpICU+JQ0KICBjb2x1bW5fdG9fcm93bmFtZXMoIkNhdGVnIikgDQoNClBhaXJfQ29tcF9wcm9wX2hpZ2hfbWF0IDwtDQogIFBhaXJfQ29tcF9wcm9wX2hpZ2ggJT4lDQogICAgcm93bmFtZXNfdG9fY29sdW1uKCJyb3duYW1lIikgJT4lDQogICAgZHBseXI6OnJlbmFtZShzdWNjZXNzID0gbikgJT4lDQogICAgbXV0YXRlKGZhaWx1cmUgPSB0b3RhbCAtIHN1Y2Nlc3MpICU+JQ0KICAgIGRwbHlyOjpzZWxlY3QoLXRvdGFsKSAlPiUNCiAgICBjb2x1bW5fdG9fcm93bmFtZXMoInJvd25hbWUiKSAlPiUNCiAgICBhcy5tYXRyaXgoKSANCg0KUGFpcl9Db21wX3Byb3BfbG93IDwtICAgICAgICMgY29tcGFpcmUgYWxsIHByb3BvcnRpb25zIHBhaXJ3aXNlDQogIFByb3BfdmFsICU+JQ0KICBmaWx0ZXIoVmFsID09ICJsb3ciKSAlPiUNCiAgZHBseXI6OnNlbGVjdCgtcGVyYykgJT4lDQogIHVuaXRlKCJDYXRlZyIsIGMoIkFubyIsICJWYWwiKSwgc2VwID0gIi0iKSAlPiUNCiAgY29sdW1uX3RvX3Jvd25hbWVzKCJDYXRlZyIpIA0KDQpQYWlyX0NvbXBfcHJvcF9sb3dfbWF0IDwtDQogIFBhaXJfQ29tcF9wcm9wX2xvdyAlPiUNCiAgcm93bmFtZXNfdG9fY29sdW1uKCJyb3duYW1lIikgJT4lDQogIGRwbHlyOjpyZW5hbWUoc3VjY2VzcyA9IG4pICU+JQ0KICBtdXRhdGUoZmFpbHVyZSA9IHRvdGFsIC0gc3VjY2VzcykgJT4lDQogIGRwbHlyOjpzZWxlY3QoLXRvdGFsKSAlPiUNCiAgY29sdW1uX3RvX3Jvd25hbWVzKCJyb3duYW1lIikgJT4lDQogIGFzLm1hdHJpeCgpDQoNCmNhdCgiIyMjIyBQYWlyd2lzZSBjb21wYXJpc29ucyB1c2luZyBQYWlyd2lzZSBjb21wYXJpc29uIG9mIHByb3BvcnRpb25zIikNCnBhaXJ3aXNlLnByb3AudGVzdCh4ID0gUGFpcl9Db21wX3Byb3BfaGlnaF9tYXQsIHAuYWRqdXN0Lm1ldGhvZCA9ICJub25lIikgJT4lIA0KICB0aWR5KCkNCnBhaXJ3aXNlLnByb3AudGVzdCh4ID0gUGFpcl9Db21wX3Byb3BfbG93X21hdCwgcC5hZGp1c3QubWV0aG9kID0gIm5vbmUiKSAlPiUgDQogIHRpZHkoKQ0KDQpjYXQoIiMjIyMgUGFpcndpc2UgY29tcGFyaXNvbnMgdXNpbmcgUGFpcndpc2UgY29tcGFyaXNvbiBvZiBwcm9wb3J0aW9ucyAoRmlzaGVyIGV4YWN0KSIpICAgICMgbGlicmFyeShmbXNiKQ0KZm1zYjo6cGFpcndpc2UuZmlzaGVyLnRlc3QoeCA9IFBhaXJfQ29tcF9wcm9wX2hpZ2hfbWF0LCBwLmFkanVzdC5tZXRob2QgPSAibm9uZSIpICU+JSANCiAgdGlkeSgpDQpmbXNiOjpwYWlyd2lzZS5maXNoZXIudGVzdCh4ID0gUGFpcl9Db21wX3Byb3BfbG93X21hdCwgcC5hZGp1c3QubWV0aG9kID0gIm5vbmUiKSAlPiUgDQogIHRpZHkoKQ0KDQoNCiMgbGlicmFyeShwYWlyY29tcHZpeikNCiMgcGFpcmNvbXB2aXo6OnBhaXJjb21wKFBhaXJfQ29tcF9wcm9wX2hpZ2gkbiwgUGFpcl9Db21wX3Byb3BfaGlnaCR0b3RhbCwgY29ycmVjdCA9IEZBTFNFLA0KIyAgICAgICAgICAgICAgICAgICAgICAgdGVzdCA9ICJwcm9wIiwgcmVzdWx0ID0gVFJVRSwgcC5hZGp1c3QubWV0aG9kID0gIm5vbmUiKSANCg0KIyBEYXRhIGZvciBQbG90DQpjYXQoIiMjIyBQcm9wb3J0aW9ucyAtIFBsb3Qgb2YgTG93LU5ldXRyYWwtSGlnaCIpDQpMaWtlcnRfdmFsIDwtIA0KICBEYXRhX1NlYXNvbl9tZWx0X25vbmEgJT4lDQogIGRwbHlyOjpzZWxlY3QoSUQsIFByb3RvY29sLCBncm91cCwgQW5vLCBWYWwpICU+JQ0KICBzcHJlYWQoa2V5ID0gQW5vLCB2YWx1ZSA9IFZhbCkgJT4lDQogIG11dGF0ZV9hdCh2YXJzKCJWYXJhIiwgIlByaW1hdmFyYSIsICJUb2FtbmEiLCAiSWFybmEiKSwgfmFzLmZhY3RvciguKSkNCg0KIyBQbG90cyAgIyBsaWJyYXJ5KGxpa2VydCkNCkxpa2VydG9ial9WYWwgPC0gbGlrZXJ0KExpa2VydF92YWxbLCBjKCJWYXJhIiwgIlByaW1hdmFyYSIsICJUb2FtbmEiLCAiSWFybmEiKV0sIG5sZXZlbHMgPSA3KSAgICMgaGVyZSBhcmUgcGVyY2VudGFnZXMNCkxpa2VydG9ial9WYWxfcGVyYyA8LSBMaWtlcnRvYmpfVmFsJHJlc3VsdHMNCiMgY2hlY2sgaWYgc2FtZSB3aXRoIFByb3AgZGF0YWZyYW1lIGFib3ZlOyBvciBwcm9wLnRhYmxlKHRhYmxlKExpa2VydF92YWwkVmFyYSkpDQoNCnBsb3QoTGlrZXJ0b2JqX1ZhbCwgdHlwZSA9ICJiYXIiLCANCiAgICAgY2VudGVyZWQgPSBUUlVFLCBjZW50ZXIgPSA0LCBpbmNsdWRlLmNlbnRlciA9IFRSVUUsICAgICAgICAgICAgICAjICI0IiBpcyBuZXV0cmFsDQogICAgIHdyYXAgPSAzMCwgbG93LmNvbG9yID0gJ2J1cmx5d29vZCcsIGhpZ2guY29sb3IgPSAnbWFyb29uJykgKw0KICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChucm93ID0gMSkpDQoNCmBgYA0KDQoNCiMjIExpa2VydCBQbG90cyBmb3IgU2Vhc29uDQoNCmBgYHtyIHJlbF9Bbm9mcmVxX1ZhbCwgcmVzdWx0cz0nYXNpcycsIGZpZy5oZWlnaHQ9NywgZmlnLndpZHRoPTcsIGZpZy5hbGlnbj0nY2VudGVyJ30NCkFub2ZyZXFfVmFsIDwtIA0KICBEYXRhX1NlYXNvbl9tZWx0X25vbmEgJT4lDQogICAgZHBseXI6OnNlbGVjdChJRCwgUHJvdG9jb2wsIEFubywgVmFsKSAlPiUNCiAgICBncm91cF9ieShJRCwgQW5vKSAlPiUNCiAgICBkcGx5cjo6c3VtbWFyaXplKE1lYW5fVmFsID0gbWVhbihWYWwsIG5hLnJtPVRSVUUpLA0KICAgICAgICAgICAgICAgICAgICAgRnJlcV9Bbm8gPSBuKCkpIA0KDQpjYXQoIiMjIyBTY2F0dGVyIHBsb3Qgd2l0aCBjb3JyZWxhdGlvbiBjb2VmZmljaWVudCBmb3IgYWxsIFNlYXNvbnMiKQ0KZ2dwdWJyOjpnZ3NjYXR0ZXIoQW5vZnJlcV9WYWwsIHggPSAiRnJlcV9Bbm8iLCB5ID0gIk1lYW5fVmFsIiwNCiAgICAgICAgICAgIGFkZCA9ICJyZWcubGluZSIsICANCiAgICAgICAgICAgIGFkZC5wYXJhbXMgPSBsaXN0KGNvbG9yID0gImJsdWUiLCBmaWxsID0gImxpZ2h0Z3JheSIpLCANCiAgICAgICAgICAgIGNvbmYuaW50ID0gVFJVRSApICsNCnN0YXRfY29yKG1ldGhvZCA9ICJwZWFyc29uIiwgbGFiZWwueCA9IDcsIGxhYmVsLnkgPSAxMCkNCg0KDQpjYXQoIiMjIyBTY2F0dGVyIHBsb3Qgd2l0aCBjb3JyZWxhdGlvbiBjb2VmZmljaWVudCBmb3IgZWFjaCBTZWFzb24iKQ0KZ2dwdWJyOjpnZ3NjYXR0ZXIoQW5vZnJlcV9WYWwsIHggPSAiRnJlcV9Bbm8iLCB5ID0gIk1lYW5fVmFsIiwNCiAgIGNvbG9yID0gIkFubyIsIHBhbGV0dGUgPSAiamNvIiwNCiAgIGFkZCA9ICJyZWcubGluZSIsIGNvbmYuaW50ID0gVFJVRSwNCiAgIHhsaW0gPSBjKDAsIDE1KSwgeWxpbSA9IGMoMCwgOCkpICsgDQpzdGF0X2NvcihhZXMoY29sb3IgPSBBbm8pLCBtZXRob2QgPSAicGVhcnNvbiIsIGxhYmVsLnggPSAxMSkNCg0KYGBgDQoNCg0KDQo8YnI+DQoNCg0KDQoNCg0KPCEtLSBTZXNzaW9uIEluZm8gYW5kIExpY2Vuc2UgLS0+DQoNCjxicj4NCg0KIyBTZXNzaW9uIEluZm8NCmBgYHtyIHNlc3Npb25faW5mbywgZWNobyA9IEZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9DQpzZXNzaW9uSW5mbygpICAgIA0KYGBgDQoNCjwhLS0gRm9vdGVyIC0tPg0KJm5ic3A7DQo8aHIgLz4NCjxwIHN0eWxlPSJ0ZXh0LWFsaWduOiBjZW50ZXI7Ij5BIHdvcmsgYnkgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL0NsYXVkaXVQYXBhc3RlcmkvIj5DbGF1ZGl1IFBhcGFzdGVyaTwvYT48L3A+DQo8cCBzdHlsZT0idGV4dC1hbGlnbjogY2VudGVyOyI+PHNwYW4gc3R5bGU9ImNvbG9yOiAjODA4MDgwOyI+PGVtPmNsYXVkaXUucGFwYXN0ZXJpQGdtYWlsLmNvbTwvZW0+PC9zcGFuPjwvcD4NCiZuYnNwOw0K